package org.usmile.algorithms.learn.linkedlist;

public class LinkedList<E> {
    private final Node<E> dummy;

    private int size;

    public LinkedList() {
        dummy = new Node<>();

        size = 0;
    }

    private static class Node<E> {
        E e;

        Node<E> next;

        public Node() {
        }

        public Node(E e) {
            this.e = e;
        }
    }

    public void add(E e) {
        Node<E> element = new Node<>(e);

        Node<E> prev = dummy;
        while (prev.next != null) {
            prev = prev.next;
        }

        prev.next = element;
        size++;
    }

    public E get(int index) {
        if (index >= size || index < 0) {
            throw new RuntimeException("Out Of Bounds");
        }

        Node<E> prev = dummy;
        for (int i = 0; i <= index; i ++) {
            prev = prev.next;
        }

        return prev.e;
    }

    public E remove(E e) {
        if (size == 0 || e == null) {
            return null;
        }

        Node<E> prev = dummy;
        while(prev.next != null) {
            if (prev.next.e.equals(e)) {
                Node<E> deleted = prev.next;
                prev.next = deleted.next;
                deleted.next = null;

                size --;

                return deleted.e;
            }
            prev = prev.next;
        }

        return null;
    }

    public int size() {
        return size;
    }
}
